c++高级篇(二)

您所在的位置:网站首页 linux io复用的系统调用 c++高级篇(二)

c++高级篇(二)

2024-07-13 23:19| 来源: 网络整理| 查看: 265

什么是IO多路复用 前言

我们在Linux上服务端一般是要同时连接多个客户端进行通信,但是为每一个客户端连接创建一个进/线程,会消耗很多资源,一个1核2GB的虚拟机,大概只能创建100多个线程,但是我们经常使用网络知道,这样是远远不能满足我们日常的使用需求的,所以为了解决这一问题,就需要我们去使用IO多路复用。

IO多路复用

IO多路复用指的是我们可以使用一个进/线程去处理多个TCP链接,减少系统开销,而我们常见的IO多路复用主要用三种:

select(1024)poll(几千)epoll(百万) 网络通讯中的读与写事件 读事件 已连接队列中有已经准备好的socket(有新的客户端连接上来)接收缓存有数据可以读(对端发送的报文已经送达)tcp连接断开(对端使用close()函数断开了连接) 写事件 发送端缓冲区没有满,可以写入数据(向对端发送报文) select模型 位图

什么是位图

select实现IO多路复用是基于位图来实现的,位图的本质是一个32位整型数组(int[32]),一个32位整型有4个字节,每个字节有8个位: 32 ∗ 8 ∗ 4 = 1024 32*8*4=1024 32∗8∗4=1024 每一个位可以监听一个socket这也是select模型课件监听1024个socket的原因所在。

位图的相关操作

在Linux内核中为我们提供相关的宏让我们操作位图:

void D_CLR(int fd,fd_set* set);//将socket从位图中删除 int FD_ISSET(int fd,fd_set *set);//判断socket是否在位图中 void FD_SET(int fd,fd_set* set);//将socket加入到位图中 void FD_ZERO(fd_set* set); //将位图全部初始化为0 select模型的细节

写事件

如果tcp的发送缓冲区没有满,那么此时socket连接是可写的一般来说发送缓冲区不容易填满,但是如果发送数据量过大或者网络带宽不够,发送缓冲区有填满的可能。

水平触发

select()监视的socket如果发生了事件,select()会返回(通知应用程序处理事件),如果事件没有被处理,再次调用select()的时候会立即再通知存在的问题 这里操作位图的方法是轮询,它的性能会随着socket的增多而降低每次调用select,需要拷贝位图,而且select属于用户态,网络通信属于内核态,需要拷贝两次,会影响select的性能受位图大小的限制,每个进/线程selectt所能处理的socket数量默认是1024个,性能不够高,无法处理网络通信频繁的实际场景 select模型监控socket通讯流程图

在这里插入图片描述

代码示例 #include "data-sharing-center/public/_cmpublic.h" #include using namespace std; int inintserver(int port); //初始化监听端口 int main(int argc,char* argv[]) { if(argc!=2) { cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3